package xgorm

import (
	"errors"
)

// 查询两个字段并返回成map数组
//
//	key	map下标字段
//	val	map值
func (c *XDB) PluckStringString(key, val string) (map[string]string, error) {
	if key == "" || val == "" {
		return nil, errors.New("抱歉, key/val不允许为空")
	}
	type temp_struct struct {
		Key string `gorm:"column:db_keys"` // 下标信息
		Val string `gorm:"column:val"`     // 查询到的值信息
	}
	m := []temp_struct{}
	switch c.DB.Dialector.Name() {
	case "mysql":
		key = "CAST(" + key + " AS CHAR) AS db_keys"
		val = "CAST(" + val + " AS CHAR) AS val"
	case "sqlserver":
		key = "CAST(" + key + " AS VARCHAR(99999)) AS db_keys"
		val = "CAST(" + val + " AS VARCHAR(99999)) AS val"
	case "sqlite", "postgres":
		key = "CAST(" + key + " AS TEXT) AS db_keys"
		val = "CAST(" + val + " AS TEXT) AS val"
	default:
		return nil, errors.New("该数据库类型驱动暂不支持Pluck方法")
	}
	err := c.Select(
		key,
		val,
	).Find(&m).Error
	if err != nil {
		return nil, err
	}
	// 追加到map列表中
	rets := map[string]string{}
	for i := 0; i < len(m); i++ {
		rets[m[i].Key] = m[i].Val
	}
	return rets, nil
}

// 查询两个字段并返回成map数组
//
//	key	map下标字段
//	val	map值
func (c *XDB) PluckStringInt(key, val string) (map[string]int, error) {
	if key == "" || val == "" {
		return nil, errors.New("抱歉, key/val不允许为空")
	}
	type temp_struct struct {
		Key string `gorm:"column:db_keys"` // 下标信息
		Val int    `gorm:"column:val"`     // 查询到的值信息
	}
	m := []temp_struct{}
	switch c.DB.Dialector.Name() {
	case "mysql":
		key = "CAST(" + key + " AS CHAR) AS db_keys"
		val = "CAST(" + val + " AS SIGNED) AS val"
	case "sqlserver":
		key = "CAST(" + key + " AS VARCHAR(99999)) AS db_keys"
		val = "CAST(" + val + " AS INT) AS val"
	case "sqlite", "postgres":
		key = "CAST(" + key + " AS TEXT) AS db_keys"
		val = "CAST(" + val + " AS INTEGER) AS val"
	default:
		return nil, errors.New("该数据库类型驱动暂不支持Pluck方法")
	}
	err := c.Select(
		key,
		val,
	).Find(&m).Error
	if err != nil {
		return nil, err
	}
	// 追加到map列表中
	rets := map[string]int{}
	for i := 0; i < len(m); i++ {
		rets[m[i].Key] = m[i].Val
	}
	return rets, nil
}

// 查询两个字段并返回成map数组
//
//	key	map下标字段
//	val	map值
func (c *XDB) PluckIntString(key, val string) (map[int]string, error) {
	if key == "" || val == "" {
		return nil, errors.New("抱歉, key/val不允许为空")
	}
	type temp_struct struct {
		Key int    `gorm:"column:db_keys"` // 下标信息
		Val string `gorm:"column:val"`     // 查询到的值信息
	}
	m := []temp_struct{}
	switch c.DB.Dialector.Name() {
	case "mysql":
		key = "CAST(" + key + " AS SIGNED) AS db_keys"
		val = "CAST(" + val + " AS CHAR) AS val"
	case "sqlserver":
		key = "CAST(" + key + " AS INT) AS db_keys"
		val = "CAST(" + val + " AS VARCHAR(99999)) AS val"
	case "sqlite", "postgres":
		key = "CAST(" + key + " AS INTEGER) AS db_keys"
		val = "CAST(" + val + " AS TEXT) AS val"
	default:
		return nil, errors.New("该数据库类型驱动暂不支持Pluck方法")
	}
	err := c.Select(
		key,
		val,
	).Find(&m).Error
	if err != nil {
		return nil, err
	}
	// 追加到map列表中
	rets := map[int]string{}
	for i := 0; i < len(m); i++ {
		rets[m[i].Key] = m[i].Val
	}
	return rets, nil
}

// 查询两个字段并返回成map数组
//
//	key	map下标字段
//	val	map值
func (c *XDB) PluckIntInt(key, val string) (map[int]int, error) {
	if key == "" || val == "" {
		return nil, errors.New("抱歉, key/val不允许为空")
	}
	type temp_struct struct {
		Key int `gorm:"column:db_keys"` // 下标信息
		Val int `gorm:"column:val"`     // 查询到的值信息
	}
	m := []temp_struct{}
	switch c.DB.Dialector.Name() {
	case "mysql":
		key = "CAST(" + key + " AS SIGNED) AS db_keys"
		val = "CAST(" + val + " AS SIGNED) AS val"
	case "sqlserver":
		key = "CAST(" + key + " AS INT) AS db_keys"
		val = "CAST(" + val + " AS INT) AS val"
	case "sqlite", "postgres":
		key = "CAST(" + key + " AS INTEGER) AS db_keys"
		val = "CAST(" + val + " AS INTEGER) AS val"
	default:
		return nil, errors.New("该数据库类型驱动暂不支持Pluck方法")
	}
	err := c.Select(
		key,
		val,
	).Find(&m).Error
	if err != nil {
		return nil, err
	}
	// 追加到map列表中
	rets := map[int]int{}
	for i := 0; i < len(m); i++ {
		rets[m[i].Key] = m[i].Val
	}
	return rets, nil
}

// 查询一个字段并返回成数组
//
//	val	要查询的字段名称
func (c *XDB) PluckString(val string) ([]string, error) {
	if val == "" {
		return nil, errors.New("抱歉, val不允许为空")
	}
	type temp_struct struct {
		Val string `gorm:"column:val"` // 查询到的值信息
	}
	m := []temp_struct{}
	switch c.DB.Dialector.Name() {
	case "mysql":
		val = "CAST(" + val + " AS CHAR) AS val"
	case "sqlserver":
		val = "CAST(" + val + " AS VARCHAR(99999)) AS val"
	case "sqlite", "postgres":
		val = "CAST(" + val + " AS TEXT) AS val"
	default:
		return nil, errors.New("该数据库类型驱动暂不支持Pluck方法")
	}
	err := c.Select(
		val,
	).Find(&m).Error
	if err != nil {
		return nil, err
	}
	// 追加到map列表中
	rets := []string{}
	for i := 0; i < len(m); i++ {
		rets = append(rets, m[i].Val)
	}
	return rets, nil
}

// 查询两个字段并返回成map数组
//
//	key	map下标字段
//	val	map值
func (c *XDB) PluckInt(val string) ([]int, error) {
	if val == "" {
		return nil, errors.New("抱歉, val不允许为空")
	}
	type temp_struct struct {
		Key int    `gorm:"column:db_keys"` // 下标信息
		Val string `gorm:"column:val"`     // 查询到的值信息
	}
	m := []temp_struct{}
	switch c.DB.Dialector.Name() {
	case "mysql":
		val = "CAST(" + val + " AS SIGNED) AS db_keys"
	case "sqlserver":
		val = "CAST(" + val + " AS INT) AS db_keys"
	case "sqlite", "postgres":
		val = "CAST(" + val + " AS INTEGER) AS db_keys"
	default:
		return nil, errors.New("该数据库类型驱动暂不支持Pluck方法")
	}
	err := c.Select(
		val,
	).Find(&m).Error
	if err != nil {
		return nil, err
	}
	// 追加到map列表中
	rets := []int{}
	for i := 0; i < len(m); i++ {
		rets = append(rets, m[i].Key)
	}
	return rets, nil
}
